import { Logger } from './logger';
import { IDebuggerConfig } from './debugConfig';

export interface IExceptionBreakpoint {
    filter: string;
    label: string;
    enabled: boolean;
    condition?: string;
}

export interface IExceptionInfo {
    id: number;
    description: string;
    breakMode: string;
    details?: {
        message?: string;
        typeName?: string;
        stackTrace?: string;
        source?: string;
    };
}

export class ExceptionManager {
    private logger: Logger;
    private config: IDebuggerConfig;
    private exceptionBreakpoints: Map<string, IExceptionBreakpoint>;
    private activeExceptions: Map<number, IExceptionInfo>;

    constructor(config: IDebuggerConfig) {
        this.config = config;
        this.logger = Logger.getInstance();
        this.exceptionBreakpoints = new Map();
        this.activeExceptions = new Map();

        // 初始化默认异常断点
        this.initializeDefaultBreakpoints();
    }

    private initializeDefaultBreakpoints(): void {
        this.addExceptionBreakpoint({
            filter: 'all',
            label: '所有异常',
            enabled: false
        });

        this.addExceptionBreakpoint({
            filter: 'uncaught',
            label: '未捕获的异常',
            enabled: true
        });

        this.addExceptionBreakpoint({
            filter: 'system',
            label: '系统异常',
            enabled: false
        });
    }

    public addExceptionBreakpoint(breakpoint: IExceptionBreakpoint): void {
        this.exceptionBreakpoints.set(breakpoint.filter, breakpoint);
        this.logger.debug(`Added exception breakpoint: ${breakpoint.label}`);
    }

    public removeExceptionBreakpoint(filter: string): void {
        this.exceptionBreakpoints.delete(filter);
        this.logger.debug(`Removed exception breakpoint: ${filter}`);
    }

    public getExceptionBreakpoints(): IExceptionBreakpoint[] {
        return Array.from(this.exceptionBreakpoints.values());
    }

    public setExceptionBreakpointEnabled(filter: string, enabled: boolean): void {
        const breakpoint = this.exceptionBreakpoints.get(filter);
        if (breakpoint) {
            breakpoint.enabled = enabled;
            this.logger.debug(`Set exception breakpoint ${filter} enabled: ${enabled}`);
        }
    }

    public setExceptionBreakpointCondition(filter: string, condition: string): void {
        const breakpoint = this.exceptionBreakpoints.get(filter);
        if (breakpoint) {
            breakpoint.condition = condition;
            this.logger.debug(`Set exception breakpoint ${filter} condition: ${condition}`);
        }
    }

    public addException(info: IExceptionInfo): void {
        this.activeExceptions.set(info.id, info);
        this.logger.debug(`Added exception: ${info.description}`);
    }

    public removeException(id: number): void {
        this.activeExceptions.delete(id);
        this.logger.debug(`Removed exception: ${id}`);
    }

    public getException(id: number): IExceptionInfo | undefined {
        return this.activeExceptions.get(id);
    }

    public getActiveExceptions(): IExceptionInfo[] {
        return Array.from(this.activeExceptions.values());
    }

    public shouldBreakOnException(info: IExceptionInfo): boolean {
        const breakpoint = this.exceptionBreakpoints.get(info.breakMode);
        if (!breakpoint || !breakpoint.enabled) {
            return false;
        }

        if (breakpoint.condition) {
            try {
                // 简单的条件评估
                const condition = breakpoint.condition
                    .replace('${exception}', info.description)
                    .replace('${type}', info.details?.typeName || '')
                    .replace('${message}', info.details?.message || '');

                return new Function('return ' + condition)();
            } catch (error) {
                this.logger.error(`Error evaluating exception condition: ${error}`);
                return false;
            }
        }

        return true;
    }

    public formatExceptionDetails(info: IExceptionInfo): string {
        let details = `异常 ID: ${info.id}\n`;
        details += `描述: ${info.description}\n`;
        details += `类型: ${info.details?.typeName || '未知'}\n`;

        if (info.details?.message) {
            details += `消息: ${info.details.message}\n`;
        }

        if (info.details?.source) {
            details += `源: ${info.details.source}\n`;
        }

        if (info.details?.stackTrace) {
            details += `堆栈跟踪:\n${info.details.stackTrace}`;
        }

        return details;
    }

    public dispose(): void {
        this.exceptionBreakpoints.clear();
        this.activeExceptions.clear();
    }
} 